#pragma once

#include <unistd.h>
#include <sys/epoll.h>
#include <string>
#include <cstring>
#include "log.hpp"
#include "err.h"

static const int size = 128;
class Epoller
{
private:
    int _epollfd;

public:
    Epoller()
    {
    }
    ~Epoller()
    {
        if (_epollfd > 0)
            close(_epollfd);
    }
    void Create()
    {
        _epollfd = epoll_create(size);
        if (_epollfd < 0)
        {
            logMessage(ERROR, "epoll create err: %s", strerror(errno));
            exit(EPOLL_CREATE_ERR);
        }
    }
    bool AddEvent(int sock, uint32_t events) // 将关心事件告诉内核
    {
        struct epoll_event ev;
        ev.data.fd = sock;
        ev.events = events;
        int n = epoll_ctl(_epollfd, EPOLL_CTL_ADD, sock, &ev);
        return n == 0;
    }
    int Wait(struct epoll_event *revs, int num, int timeout) // revs存放就绪事件及其fd的数组，num最大获取个数
    {
        return epoll_wait(_epollfd, revs, num, timeout); // 返回已就绪事件个数
    }
    bool Control(int sock, uint32_t event, int action)
    {
        bool n = 0;
        if (action == EPOLL_CTL_DEL)
        {
            struct epoll_event ev;
            ev.data.fd = sock;
            ev.events = event;
            n = epoll_ctl(_epollfd, EPOLL_CTL_DEL, sock, &ev);
        }
        else if (action == EPOLL_CTL_MOD) // ET模式
        {
            n = epoll_ctl(_epollfd, EPOLL_CTL_MOD, sock, nullptr); // 设置用ET模式检测某个事件，最后参数nullptr
        }
        else
            n = -1; // 错误action
        return n == 0;
    }
    void Close()
    {
        if (_epollfd >= 0)
            close(_epollfd);
    }
};